home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Educational / Sphere / Source / SphereDrawerObject.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  6.7 KB  |  293 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "SphereDrawerObject.h"
  5. #import "SphereControl.h"
  6. #import <math.h>
  7. #import <dpsclient/wraps.h>
  8. #import <appkit/appkit.h>
  9. #import "DrawPoly.h"
  10.  
  11. #define PI (3.14159265)
  12.  
  13. typedef float vector3D[3];
  14.  
  15. typedef int boolean;
  16. typedef struct PointThreeD {
  17.     float x,y,z;
  18. } PointThreeD;
  19.  
  20. typedef struct PointTwoD {
  21.     float x,y;
  22. } PointTwoD;
  23.  
  24. boolean clipFlag=FALSE, shadeFlag=FALSE;
  25. float gray, sinTheta, cosTheta, sinPhi, cosPhi, xMiddle=0, yMiddle=0;
  26. int xSize = 400, ySize = 400;
  27.  
  28. /***************************************************************/
  29.  
  30. void CrossXYZ(v1, v2, crossProd)
  31.     vector3D v1, v2, crossProd;
  32. {
  33.     crossProd[0] = v1[1] * v2[2] - v1[2] * v2[1];
  34.     crossProd[1] = v1[2] * v2[0] - v1[0] * v2[2];
  35.     crossProd[2] = v1[0] * v2[1] - v1[1] * v2[0];
  36. }
  37.  
  38. /***************************************************************/
  39.  
  40. boolean PolyVisible(poly)
  41.     PointThreeD *poly;
  42. {
  43.     vector3D v1, v2, cross;
  44.     
  45.     v1[0] = poly[0].x - poly[1].x;
  46.     v1[1] = poly[0].y - poly[1].y;
  47.     v1[2] = poly[0].z - poly[1].z;
  48.  
  49.     v2[0] = poly[2].x - poly[1].x;
  50.     v2[1] = poly[2].y - poly[1].y;
  51.     v2[2] = poly[2].z - poly[1].z;
  52.  
  53.     CrossXYZ(v1, v2, cross);
  54.     if (cross[2] < 0) return (TRUE);
  55.     else return (FALSE);
  56.     
  57. }
  58.  
  59. /***************************************************************/
  60.  
  61. void CalcLight(poly)
  62.     PointThreeD *poly;
  63. {
  64.     vector3D v1, v2, cross;
  65.     
  66.     v1[0] = poly[0].x - poly[1].x;
  67.     v1[1] = poly[0].y - poly[1].y;
  68.     v1[2] = poly[0].z - poly[1].z;
  69.  
  70.     v2[0] = poly[2].x - poly[1].x;
  71.     v2[1] = poly[2].y - poly[1].y;
  72.     v2[2] = poly[2].z - poly[1].z;
  73.  
  74.     CrossXYZ(v1, v2, cross);
  75.     gray = -cross[2] / sqrt(cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]);
  76. }
  77.  
  78. /***************************************************************/
  79.  
  80. void Rotate(px, py, pz)
  81.     float *px, *py, *pz;
  82. {
  83.     float xt, yt;
  84.     
  85.     xt = *pz * sinTheta + *px * cosTheta;
  86.     *pz = *pz * cosTheta - *px * sinTheta;
  87.     *px = xt;
  88.     
  89.     yt = *py * cosPhi - *pz * sinPhi;
  90.     *pz = *py * sinTheta + *pz * cosPhi;
  91.     *py = yt;
  92. }
  93.  
  94. /***************************************************************/
  95.  
  96. void DrawPolygon(curPoly)
  97.     PointThreeD curPoly[];
  98. {
  99.     boolean drawFlag=FALSE;
  100.     
  101.     if (shadeFlag==TRUE) CalcLight(curPoly);
  102.     
  103.     Rotate(&curPoly[0].x, &curPoly[0].y, &curPoly[0].z);
  104.     Rotate(&curPoly[1].x, &curPoly[1].y, &curPoly[1].z);
  105.     Rotate(&curPoly[2].x, &curPoly[2].y, &curPoly[2].z);
  106.     Rotate(&curPoly[3].x, &curPoly[3].y, &curPoly[3].z);
  107.  
  108.     if (clipFlag==TRUE) drawFlag = PolyVisible(curPoly);
  109.     if ((clipFlag && drawFlag) || (clipFlag == FALSE))
  110.     {
  111.         if (shadeFlag==FALSE)
  112.         
  113.             DrawPoly4(xMiddle + curPoly[0].x, yMiddle + curPoly[0].y,
  114.                       xMiddle + curPoly[1].x, yMiddle + curPoly[1].y,
  115.                       xMiddle + curPoly[2].x, yMiddle + curPoly[2].y,
  116.                       xMiddle + curPoly[3].x, yMiddle + curPoly[3].y);
  117.         else
  118.         
  119.             DrawPoly4s(xMiddle + curPoly[0].x, yMiddle + curPoly[0].y,
  120.                        xMiddle + curPoly[1].x, yMiddle + curPoly[1].y,
  121.                        xMiddle + curPoly[2].x, yMiddle + curPoly[2].y,
  122.                        xMiddle + curPoly[3].x, yMiddle + curPoly[3].y, 
  123.                        gray);
  124.                 
  125.     
  126.     }
  127. }
  128.  
  129. void DrawPolygon3(curPoly)
  130.     PointThreeD curPoly[];
  131. {
  132.     boolean drawFlag=FALSE;
  133.     
  134.     if (shadeFlag==TRUE) CalcLight(curPoly);
  135.     
  136.     Rotate(&curPoly[0].x, &curPoly[0].y, &curPoly[0].z);
  137.     Rotate(&curPoly[1].x, &curPoly[1].y, &curPoly[1].z);
  138.     Rotate(&curPoly[2].x, &curPoly[2].y, &curPoly[2].z);
  139.  
  140.     if (clipFlag==TRUE) drawFlag = PolyVisible(curPoly);
  141.     if ((clipFlag && drawFlag) || (clipFlag == FALSE))
  142.         {
  143.         if (shadeFlag==FALSE)
  144.         
  145.             DrawPoly3(xMiddle + curPoly[0].x, yMiddle + curPoly[0].y,
  146.                       xMiddle + curPoly[1].x, yMiddle + curPoly[1].y,
  147.                       xMiddle + curPoly[2].x, yMiddle + curPoly[2].y);
  148.         else
  149.             DrawPoly3s(xMiddle + curPoly[0].x, yMiddle + curPoly[0].y,
  150.                        xMiddle + curPoly[1].x, yMiddle + curPoly[1].y,
  151.                        xMiddle + curPoly[2].x, yMiddle + curPoly[2].y,
  152.                        gray);
  153.  
  154.         }
  155. }
  156.  
  157. /***************************************************************/
  158.  
  159.  
  160.  
  161.  
  162.  
  163. @implementation SphereDrawerObject
  164.  
  165. - init
  166. {
  167.     [super init];
  168.     return self;
  169. }
  170.  
  171. - computeSphere
  172. {
  173.     float step1=0, step2=0, count1=0, count2=0, s1=0, s2=0, c1=0, c2=0, ts1=0, ts2=0, tc1=0, tc2=0;
  174.     int radius=0;
  175.     PointThreeD curPoly[4];
  176.     
  177.     xMiddle = xSize / 2;
  178.     yMiddle = ySize / 2;
  179.  
  180.     sinTheta = sin(-[sphereControlPtr readTheta]/180.0*PI);
  181.     sinPhi = sin([sphereControlPtr readPhi]/180.0*PI);
  182.     cosTheta = cos(-[sphereControlPtr readTheta]/180.0*PI);
  183.     cosPhi = cos([sphereControlPtr readPhi]/180.0*PI);
  184.     
  185.     
  186.     step1 = PI / [sphereControlPtr readLat];
  187.     step2 = PI / [sphereControlPtr readLong];
  188.     radius = [sphereControlPtr readRadius];
  189.     clipFlag=[sphereControlPtr readHideFlag];
  190.     shadeFlag=[sphereControlPtr readShadeFlag];
  191.  
  192.  
  193. /************ Draw Top Row *******************/
  194.     c1 = 1;
  195.     s1 = 0;
  196.     tc1 = cos(step1);
  197.     ts1 = sin(step1);
  198.     for (count2 = 0; count2 < PI * 2; count2 = count2 + step2)
  199.     {
  200.         curPoly[0].x=0;
  201.         curPoly[0].y=radius;
  202.         curPoly[0].z=0;
  203.  
  204.         c2 = cos(count2);
  205.         s2 = sin(count2);
  206.         tc2 = cos(count2+step2);
  207.         ts2 = sin(count2+step2);
  208.             
  209.         curPoly[1].x = ts1 * tc2 * radius;
  210.         curPoly[1].y = tc1 * radius;
  211.         curPoly[1].z = ts1 * ts2 * radius;
  212.  
  213.         curPoly[2].x = ts1 * c2 * radius;
  214.         curPoly[2].y = tc1 * radius;
  215.         curPoly[2].z = ts1 * s2 * radius;
  216.  
  217.         DrawPolygon3(curPoly);
  218.         
  219.         if ([sphereControlPtr readAutoDraw]==FALSE) PSflushgraphics();
  220.     }
  221.  
  222. /************ Draw Body of Sphere *******************/
  223.     for (count1 = step1; count1 < (PI-step1); count1 = count1 + step1)
  224.     {
  225.         c1 = cos(count1);
  226.         s1 = sin(count1);
  227.         tc1 = cos(count1+step1);
  228.         ts1 = sin(count1+step1);
  229.         
  230.         for (count2 = 0; count2 < PI * 2; count2 = count2 + step2)
  231.         {
  232.             c2 = cos(count2);
  233.             s2 = sin(count2);
  234.             tc2 = cos(count2+step2);
  235.             ts2 = sin(count2+step2);
  236.             
  237.             curPoly[0].x = s1 * c2 * radius;
  238.             curPoly[0].y = c1 * radius;
  239.             curPoly[0].z = s1 * s2 * radius;
  240.  
  241.             curPoly[1].x = s1 * tc2 * radius;
  242.             curPoly[1].y = c1 * radius;
  243.             curPoly[1].z = s1 * ts2 * radius;
  244.             
  245.             curPoly[2].x = ts1 * tc2 * radius;
  246.             curPoly[2].y = tc1 * radius;
  247.             curPoly[2].z = ts1 * ts2 * radius;
  248.             
  249.             curPoly[3].x = ts1 * c2 * radius;
  250.             curPoly[3].y = tc1 * radius;
  251.             curPoly[3].z = ts1 * s2 * radius;
  252.             
  253.             DrawPolygon(curPoly);
  254.         
  255.             if ([sphereControlPtr readAutoDraw]==FALSE) PSflushgraphics();
  256.         }
  257.     }
  258.  
  259. /************ Draw Bottom Row *******************/
  260.     c1 = -1;
  261.     s1 = 0;
  262.     tc1 = cos(PI-step1);
  263.     ts1 = sin(PI-step1);
  264.     for (count2 = 0; count2 < PI * 2; count2 = count2 + step2)
  265.     {
  266.         curPoly[0].x=0;
  267.         curPoly[0].y=-radius;
  268.         curPoly[0].z=0;
  269.  
  270.         c2 = cos(count2);
  271.         s2 = sin(count2);
  272.         tc2 = cos(count2+step2);
  273.         ts2 = sin(count2+step2);
  274.  
  275.         curPoly[1].x = ts1 * c2 * radius;
  276.         curPoly[1].y = tc1 * radius;
  277.         curPoly[1].z = ts1 * s2 * radius;
  278.             
  279.         curPoly[2].x = ts1 * tc2 * radius;
  280.         curPoly[2].y = tc1 * radius;
  281.         curPoly[2].z = ts1 * ts2 * radius;
  282.  
  283.         DrawPolygon3(curPoly);
  284.         
  285.         if ([sphereControlPtr readAutoDraw]==FALSE) PSflushgraphics();
  286.     }
  287.  
  288.     return self;
  289. }
  290.  
  291.  
  292. @end
  293.